package scau.mis4.chanyulin.utils;

import java.util.Stack;

/**
 * Created by cyl on 2017/12/28.
 * 位（0和1）工具类
 */
public class BitsUtils {

    /**
     * 十进制转二进制，支持用0进行补位
     * @param dec
     * @return
     */
    public static byte[] fromDec(int dec, int len) {
        byte[] temp = fromDec(dec);
        int dis = len - temp.length;
        if (dis != 0) {
            byte[] result = new byte[len];
            for (int i = 0; i < dis; i++) result[i] = 0;
            for (int j = dis; j < len; j++) result[j] = temp[j - dis];
            return result;
        } else
            return temp;
    }

    /**
     * 十进制转二进制
     * @param dec
     * @return
     */
    public static byte[] fromDec(int dec) {
        int div = dec;   // 用于保存商
        int mod;     // 用于保存余数
        Stack<Byte> stack = new Stack<>();   // 初始化一个栈，用于保存二进制结果
        // 递归运算，使十进制数不断除以2和模2
        do {
            mod = div % 2;
            stack.push((byte) mod);
            div = div / 2;
        } while (div != 0);
        int size = stack.size();
        byte[] result = new byte[size];
        for (int i = 0; i < size; i++) result[i] = stack.pop();
        return result;
    }

    /**
     * 任意长度的二进制转为十进制
     * @param bits
     * @return
     */
    public static int toDec(byte[] bits) {
        int result = 0;
        for (int i = 0; i < bits.length; i++)
            if (bits[i] == 1) result += Math.pow(2, bits.length - 1 - i);
        return result;
    }

    /**
     * 两个位数组求异或（相加）
     * @param b1
     * @param b2
     * @return
     */
    public static byte[] xor(byte[] b1, byte[] b2) {
        if (b1.length != b2.length) return null;
        byte[] result = new byte[b1.length];
        for (int i = 0; i < b1.length; i++) {
            byte temp = b1[i];
            temp ^= b2[i];
            result[i] = temp;
        }
        return result;
    }

    /**
     * 两个字节求异或
     * @param b1
     * @param b2
     * @return
     */
    public static byte xor(byte b1, byte b2) {
        byte result = b1;
        result ^= b2;
        return result;
    }

    /**
     * 判断某个位数组是否为1
     * @param target
     * @return
     */
    public static boolean isOne(byte[] target) {
        for (int i = 0; i < target.length - 1; i++)
            if (target[i] != 0) return false;
        if (target[target.length - 1] != 1) return false;
        return true;
    }

    /**
     * 字节数组转为位数组
     * @param bytes
     * @return
     */
    public static byte[] fromBytes(byte[] bytes) {
        byte[] bits = new byte[0];
        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];
            bits = ByteUtils.appendBytes(bits, fromByte(b));
        }
        return bits;
    }

    /**
     * 将字节转为用0和1表示的位数组
     * @param b
     * @return
     */
    public static byte[] fromByte(byte b) {
        byte[] array = new byte[8];
        for (int i = 7; i >= 0; i--) {
            array[i] = (byte) (b & 1);
            b = (byte) (b >> 1);
        }
        return array;
    }

    /**
     * 将位数组转为字节
     * @param bits
     * @return
     */
    public static byte toByte(byte[] bits) {
        byte result = 0;
        for (int i = 7; i >= 0; i--) {
            byte b = bits[i];
            b = (byte) (b << 7 - i);
            result ^= b;
        }
        return result;
    }

    /**
     * 判断两个位数组是否相等
     * @param bytes1
     * @param bytes2
     * @return
     */
    public static boolean isEqual(byte[] bytes1, byte[] bytes2) {
        if (bytes1.length != bytes2.length) return false;
        for (int i = 0; i < bytes1.length; i++) {
            if (bytes1[i] != bytes2[i]) return false;
        }
        return true;
    }

    /**
     * 获取位数组的最高位
     * @param bits
     * @return 错误返回-1
     */
    public static int getTopPos(byte[] bits) {
        for (int i = 0; i < bits.length; i++) {
            if (bits[i] == 1) return bits.length - 1 - i;
        }
        return -1;
    }

}
